package com.wzb.mybatisplus.bitaction;

import com.wzb.mybatisplus.bitaction.electrumaction.FileUtils;
import com.wzb.mybatisplus.bitaction.electrumaction.one.BitcoinKeyConverter;
import com.wzb.mybatisplus.bitaction.electrumaction.one.KeyPair;
import org.bitcoinj.core.Base58;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Random;

public class BitcoinPrivateKeyGenerator1 {

    private static final BigInteger CURVE_ORDER = new BigInteger(
            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16
    );
    private static final BigInteger MIN_PRIVATE_KEY = BigInteger.ONE;

    /**
     * 生成有效的比特币私钥
     */
    public static BitcoinPrivateKey generatePrivateKey() {
        try {
            SecureRandom secureRandom = SecureRandom.getInstanceStrong(); // 使用强随机数
            BigInteger privateKeyNum;

            // 确保私钥在有效范围内
            do {
                byte[] privateKeyBytes = new byte[32];
                secureRandom.nextBytes(privateKeyBytes);
                privateKeyNum = new BigInteger(1, privateKeyBytes).add(new BigInteger("1"));

            } while (!isValidPrivateKey(privateKeyNum));

            return new BitcoinPrivateKey(privateKeyNum);

        } catch (Exception e) {
            throw new RuntimeException("生成私钥失败", e);
        }
    }
    public static BitcoinPrivateKeyGenerator1.BitcoinPrivateKey generatePrivateKey(BigInteger privateKeyNum,BigInteger num) {
        try {
//            SecureRandom secureRandom = SecureRandom.getInstanceStrong(); // 使用强随机数

            for(;;){
                if(isValidPrivateKey(privateKeyNum)){break;}
                privateKeyNum = privateKeyNum.add(num);
                if(privateKeyNum.compareTo(MIN_PRIVATE_KEY) < 0   || privateKeyNum.compareTo(CURVE_ORDER) > 0){
//                    System.out.println("超过数据了跳出循环");
//                    System.exit(1);
                    return null;
                }
            }

            return new BitcoinPrivateKeyGenerator1.BitcoinPrivateKey(privateKeyNum);

        } catch (Exception e) {
            throw new RuntimeException("生成私钥失败", e);
        }
    }

    public static BitcoinPrivateKeyGenerator1.BitcoinPrivateKey generatePrivateKeyDe(BigInteger privateKeyNum,String dicide ,BigInteger num) {
        try {
//            SecureRandom secureRandom = SecureRandom.getInstanceStrong(); // 使用强随机数

            for(;;){
//                if(privateKeyNum.compareTo() < 0){
//
//                }
                if(isValidPrivateKey(privateKeyNum)){break;}
                privateKeyNum = privateKeyNum.multiply(new BigInteger(dicide)).divide(num);
                if(privateKeyNum.compareTo(new BigInteger("1000000")) < 0 ){
                    System.out.println("超过数据了跳出循环");
                    System.exit(1);
                }
            }

            return new BitcoinPrivateKeyGenerator1.BitcoinPrivateKey(privateKeyNum);

        } catch (Exception e) {
            throw new RuntimeException("生成私钥失败", e);
        }
    }
    /**
     * 检查私钥是否在有效范围内
     */
    public static boolean isValidPrivateKey(BigInteger privateKey) {
        return privateKey.compareTo(MIN_PRIVATE_KEY) >= 0 &&
                privateKey.compareTo(CURVE_ORDER) < 0;
    }

    /**
     * 比特币私钥包装类
     */
    public static class BitcoinPrivateKey {
        private final BigInteger privateKey;
        private final String hexFormat;
        private final String wifCompressed;
        private final String wifUncompressed;

        public BitcoinPrivateKey(BigInteger privateKey) {
            this.privateKey = privateKey;
            this.hexFormat = privateKey.toString(16).toUpperCase();
            this.wifCompressed = toWIF(true);
            this.wifUncompressed = toWIF(false);
        }

        /**
         * 转换为WIF格式
         */
        private String toWIF(boolean compressed) {
            try {
                // 1. 添加版本字节 (0x80 for mainnet)
                byte[] versioned = new byte[compressed ? 34 : 33];
                versioned[0] = (byte) 0x80;

                // 2. 添加私钥字节（处理前导零）
                byte[] privBytes = privateKey.toByteArray();
                int start = privBytes[0] == 0 ? 1 : 0; // 跳过符号字节
                int length = privBytes.length - start;
                System.arraycopy(privBytes, start, versioned, 33 - length, length);

                // 3. 如果压缩，添加压缩标志
                if (compressed) {
                    versioned[33] = 0x01;
                }

                // 4. 计算校验和
                byte[] checksum = doubleSHA256(versioned);

                // 5. 组合并Base58编码
                byte[] wifBytes = new byte[versioned.length + 4];
                System.arraycopy(versioned, 0, wifBytes, 0, versioned.length);
                System.arraycopy(checksum, 0, wifBytes, versioned.length, 4);

                return base58Encode(wifBytes);

            } catch (Exception e) {
                throw new RuntimeException("WIF转换失败", e);
            }
        }

        private byte[] doubleSHA256(byte[] data) throws Exception {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash1 = digest.digest(data);
            return Arrays.copyOf(digest.digest(hash1), 4); // 前4字节作为校验和
        }

        private String base58Encode(byte[] input) {
            // Base58编码实现（同上一个回答）
            // 这里省略具体实现以保持简洁
            return Base58.encode(input);
        }

        // Getter方法
        public String getHex() { return hexFormat; }
        public String getWIFCompressed() { return wifCompressed; }
        public String getWIFUncompressed() { return wifUncompressed; }
        public BigInteger getPrivateKey() { return privateKey; }

        @Override
        public String toString() {
            return String.format(
                    "私钥 (十六进制): %s\nWIF压缩格式: %s\nWIF非压缩格式: %s",
                    hexFormat, wifCompressed, wifUncompressed
            );
        }
    }

    public static void main(String[] args) {
//        String path = "D:\\btc\\miyao\\110.txt";
//        FileUtils fileUtils = new FileUtils();
//        fileUtils.createFile(path);
//        fileUtils.writeFile("赚钱","D:\\btc\\miyao\\1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa.txt");
//        fileUtils.writeFile("破解","D:\\btc\\miyao\\1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa.txt")


        // 生成多个私钥进行测试
//        for (int i = 0; i < 5000; i++) {
//            BitcoinPrivateKey privateKey = generatePrivateKey();
//            System.out.println("=== 私钥 #" + (i + 1) + " ===");
//            System.out.println(privateKey);
//            System.out.println("有效性检查: " +
//                    isValidPrivateKey(privateKey.getPrivateKey()));
//            if(isValidPrivateKey(privateKey.getPrivateKey())){
//
//                fileUtils.writeFile( privateKey.getWIFCompressed()+"\n",path);
//
//
//            }
//            System.out.println();
//        }
        BitcoinPrivateKey privateKey = generatePrivateKey(new BigInteger("26"),new BigInteger("1"));

        String wifPrivateKey = privateKey.getWIFCompressed();

        KeyPair wifKeyPair = null;
        try {
            wifKeyPair = BitcoinKeyConverter.generateFromWIF(wifPrivateKey);
        } catch (Exception e) {

        }
//        if(wifKeyPair==null){
//            sy = new BigInteger(privateKey.getHex(),16).add(new BigInteger(add));
//            continue;
//        }
        String address = wifKeyPair.getLegacyAddress(); // 比特币创始区块地址公钥地址

    }
}
